#ifndef SHAREDMEMORY_H
#define SHAREDMEMORY_H

#include <QObject>
#include <QVariant>
#include <QReadWriteLock>
#include <QMutex>
#include <QHash>

#include <utility>

#include "common_global.h"

struct MemeryItem{
    QString         name;
    void*           data;
    QReadWriteLock  locker;
};

enum MemError{
    OK,
    Exist,
    NotExist,
    GetLockFailed,
};

class SharedMemoryPrivate;

class COMMONSHARED_EXPORT SharedMemory : public QObject
{
    Q_OBJECT
private:
    static SharedMemory sInst;
public:
    static SharedMemory* GetInstance(){
        return &sInst;
    }

    template<class T>
    MemError CreateMem(QString name){
        MemError err;
        T* p = new T;
        err = CreateMemP(name,(void*)p);
        if(err != OK){
            delete p;
        }
        return err;
    }

    template<class T, class arg1>
    MemError CreateMem1(QString name, arg1 a1){
        MemError err;
        T* p = new T(a1);
        err = CreateMemP(name,(void*)p);
        if(err != OK){
            delete p;
        }

        return err;
    }

    template<class T, class arg1, class arg2>
    MemError CreateMem2(QString name, arg1 a1, arg2 a2){
        MemError err;
        T* p = new T(a1,a2);
        err = CreateMemP(name,(void*)p);
        if(err != OK){
            delete p;
        }

        return err;
    }

    template<class T>
    MemError DeleteMem(QString name){
        MemError err;

        MemeryItem* item;
        err = GetMemItemWriteLock(name,&item);
        if(err != OK){
          return err;
        }

        delete item;
        RemoveMemItem(name);

        UnlockMem(name);

    }

    MemError GetMemItemWriteLock(QString name, MemeryItem** item);

    MemError CreateMemP(QString name, void* handle);

    MemError GetMemReadLock(QString name,const void** phandle);

    MemError GetMemWriteLock(QString name, void** phandle);

    MemError UnlockMem(QString name);

    MemError RemoveMemItem(QString name);
signals:

public slots:

private:
    SharedMemory();
    ~SharedMemory();

    SharedMemory(const SharedMemory&) = delete;
    SharedMemory& operator=(const SharedMemory&) = delete;

    SharedMemoryPrivate* _p = nullptr;
};

#endif // SHAREDMEMORY_H
